package com.hly.musicbackground.model.music.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hly.musicbackground.Enum.SongEnum;
import com.hly.musicbackground.Enum.SortEnum;
import com.hly.musicbackground.Final.SongLinkFinal;
import com.hly.musicbackground.Utils.RequestContextUtils;
import com.hly.musicbackground.Utils.StringUtils;
import com.hly.musicbackground.Utils.ThreadPoolUtils;
import com.hly.musicbackground.dao.SongDao;
import com.hly.musicbackground.domain.Fiction;
import com.hly.musicbackground.domain.Song;
import com.hly.musicbackground.model.music.VO.MusicListVO;
import com.hly.musicbackground.model.music.VO.SongDetailVO;
import com.hly.musicbackground.model.music.VO.SongQueryDataVO;
import com.hly.musicbackground.model.music.params.SongQueryParams;
import com.hly.musicbackground.model.music.service.SongLinkService;
import com.hly.musicbackground.model.music.service.SongService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SongServiceImpl extends ServiceImpl<SongDao, Song> implements SongService {

    @Override
    public boolean isMp4(int rid) {
        Song song = lambdaQuery().eq(Song::getRid, rid)
                .eq(Song::getHasmv, SongEnum.MV.getStatus()).one();
        if (song == null){
            return false;
        }
        return true;
    }

    @Override
    @Async
    public void SaveList(List<Song> list) {
        ThreadPoolUtils.start(() -> {
            for (Song song : list){
                if (lambdaQuery().eq(Song::getRid, song.getRid()).one() == null){
                    save(song);
                }
            }
        });
    }

    @Override
    public List<Song> getSortList(String sortName, String type, int page, int limit) {
        String mp3 = SongEnum.MP3.getValue();
        String mp4 = SongEnum.MP4.getValue();
        String desc = SortEnum.DESC.getValue();
        String asc = SortEnum.ASC.getValue();
        return lambdaQuery()
                .eq(mp4.equals(sortName), Song::getStatus, SongEnum.STATUS_OK.getStatus())
                .orderByAsc(mp3.equals(sortName) && asc.equals(type),
                        Song::getPlayMp3Num)
                .orderByDesc(mp3.equals(sortName) && desc.equals(type),
                        Song::getPlayMp3Num)
                .orderByAsc(mp4.equals(sortName) && asc.equals(type),
                        Song::getPlayMp4Num)
                .orderByDesc(mp4.equals(sortName) && desc.equals(type),
                        Song::getPlayMp4Num)
                .orderByDesc(Song::getReleaseDate)
                .eq(mp4.equals(sortName), Song::getHasmv, SongEnum.MV.getStatus())
        .page(new Page<Song>(page, limit)).getRecords();
    }

    @Override
    public List<Song> getErrorList() {
        return lambdaQuery().eq(Song::getStatus, SongEnum.STATUS_ERROR.getStatus()).list();
    }

    @Override
    public void error(int rid) {
        Song song = new Song();
        song.setRid(rid);
        song.setStatus(SongEnum.STATUS_ERROR.getStatus());
        baseMapper.updateStatus(song);
    }

    @Override
    public void playMp3NumAutoincrement(int rid) {
        baseMapper.playMp3NumAutoincrement(rid);
    }

    @Override
    public void playMp4NumAutoincrement(int rid) {
        baseMapper.playMp4NumAutoincrement(rid);
    }

    @Override
    public void updateStatus(Song song) {
        baseMapper.updateStatus(song);
    }

    @Override
    public String getSongSheetPic(int songSheetId) {
        return baseMapper.getSongSheetPic(songSheetId);
    }

    @Override
    public List<Song> getRandomList(int limit, Set<Integer> ids, int max) {
        if (max == 0){
            Map<String, Object> map = baseMapper.selectMaps(query().select("max(song_id) as len")).get(0);
            max = Integer.valueOf(String.valueOf(map.get("len")));
        }
        if (ids == null){
//            ids = new <>();
        }
        Random random = new Random();
        for (int i = 0; i < limit; i++) {
            random.nextInt();
        }
        return null;
    }

    @Override
    public MusicListVO getQueryList(SongQueryParams params) {
        MusicListVO listVO = new MusicListVO();
        QueryWrapper<Song> query = new QueryWrapper<>();

        query.lambda()

                //最小发布时间
                .gt(params.getMinTime() != null,
                        Song::getReleaseDate, params.getMinTime())

                //最大发布时间
                .lt(params.getMaxTime() != null,
                        Song::getReleaseDate, params.getMaxTime())

                //是否有MV
                .eq(params.getIsMV() != 0,
                        Song::getHasmv, params.getIsMV());

        //搜索关键字
        if (StringUtils.isNotEmpty(params.getKey())){
            query.lambda().and(n -> {
                n.like(Song::getArtist, params.getKey())
                .or()
                .like(Song::getName, params.getKey());
            });
        }

        //排序
        if (StringUtils.isNotEmpty(params.getSort())){

            String[] split = params.getSort().split(";");

            for (int i = 0; i < split.length; i++) {
                String[] s = split[i].split(":");
                query.orderBy(true, SortEnum.ASC.getValue().equals(s[1]), s[0]);
            }

        }

        Page<Song> page = baseMapper.selectPage(new Page<>(params.getPage(),
                params.getLimit()), query);

        listVO.setList(page.getRecords());
        listVO.setTotal((int) page.getTotal());

        return listVO;
    }

    @Override
    public List<SongQueryDataVO> songQueryData() {
        return null;
    }

    @Override
    public SongDetailVO getDetail(int rid) {
        return SongDetailVO.builder().build();
    }
}
